package com.ssm.user.redislua;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

//RedisLua工具类用于初始化RedisLua脚本的初始环境
@Component
@Slf4j
public class CompareAndSetLua {

    @Resource
    private RedisTemplate redisTemplate;

    //DefaultRedisScript类是Spring Data Redis提供的一个类，用于封装Redis脚本的执行
    private DefaultRedisScript<Boolean> casScript;

    //初始化环境
    @PostConstruct //在Spring容器初始化这个Bean之后自动执行。这样做的目的是在Bean的实例化之后，立即执行一些初始化操作，比如加载Redis脚本。
    public void init() {
        casScript = new DefaultRedisScript<>();
        casScript.setResultType(Boolean.class); //设置脚本执行后返回的结果类型
        //ResourceScriptSource来指定脚本的来源,ClassPathResource用于加载类路径下的资源
        casScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("compareAndSet.lua")));
    }

    //调用Lua脚本
    public boolean compareAndSet(String key, Long oldValue, Long newValue) {
        //lua中接收key的为KEYS数组类型,所以我们要传递集合类型
        List<String> keys = new ArrayList<>();
        keys.add(key);
        //casScript在bean初始化时已赋值
        Boolean result = (Boolean) redisTemplate.execute(casScript, keys, oldValue, newValue);
        return result;
    }

}
